﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NGIS.Data;
using NGIS.Data.Schema;

namespace DataMappingTemplateDotNet
{
    public class MethodImp
    {
        private static UdxDatasetSchema mUdxSchema = null;
        private static List<UdxNodeSchema> mCapabilities = null;
        private static List<int> mReadNodeIndex_Collection = new List<int>(100);

        /// <summary>
        /// 获取数据映射方法的版本
        /// </summary>
        /// <returns>返回数据映射方法的版本，String类型</returns>
        public static string getVersion_imp()
        {
            //! TODO
            return "1.0.0.0";
        }

        /// <summary>
        /// 获取数据映射方法的名称
        /// </summary>
        /// <returns>返回数据映射方法的名称，String类型</returns>
        public static string getName_imp()
        {
            //! TODO
            return "Mapping Method Name";
        }

        /// <summary>
        /// 获取数据映射方法关联的UDX Schema
        /// </summary>
        /// <returns>返回UDX Scheme，XML String类型</returns>
        public static string getSchema_imp()
        {
            //! TODO
            if (mUdxSchema == null)
            {
                mUdxSchema = new UdxDatasetSchema(null, "UdxDeclaration");
                UdxNodeSchema headerNode = mUdxSchema.addChildNode("header", ESchemaNodeType.EDTKT_NODE);
                UdxNodeSchema bandsNode = mUdxSchema.addChildNode("Bands", ESchemaNodeType.EDTKT_LIST);

                headerNode.addChildNode("UpperLeftX", ESchemaNodeType.EDTKT_REAL);
                headerNode.addChildNode("PixelWidth", ESchemaNodeType.EDTKT_REAL);
                headerNode.addChildNode("TransParam1", ESchemaNodeType.EDTKT_REAL);
                headerNode.addChildNode("UpperLeftY", ESchemaNodeType.EDTKT_REAL);
                headerNode.addChildNode("TransParam2", ESchemaNodeType.EDTKT_REAL);
                headerNode.addChildNode("PixelHeight", ESchemaNodeType.EDTKT_REAL);
                headerNode.addChildNode("Width", ESchemaNodeType.EDTKT_INT);
                headerNode.addChildNode("Height", ESchemaNodeType.EDTKT_INT);
                headerNode.addChildNode("BandCount", ESchemaNodeType.EDTKT_INT);

                UdxNodeSchema band_node = bandsNode.addChildNode("Band_Item", ESchemaNodeType.EDTKT_NODE);
                band_node.addChildNode("NoDataValue", ESchemaNodeType.EDTKT_REAL);
                band_node.addChildNode("Scale", ESchemaNodeType.EDTKT_REAL);
                band_node.addChildNode("Offset", ESchemaNodeType.EDTKT_REAL);
                band_node.addChildNode("UnitType", ESchemaNodeType.EDTKT_STRING);
                band_node.addChildNode("DataType", ESchemaNodeType.EDTKT_INT);

                UdxNodeSchema value_node = band_node.addChildNode("Value", ESchemaNodeType.EDTKT_LIST);
                value_node.addChildNode("Row_Item", ESchemaNodeType.EDTKT_REAL | ESchemaNodeType.EDTKT_LIST);

                UdxNodeSchema projection_node = mUdxSchema.addChildNode("Projection", ESchemaNodeType.EDTKT_STRING);
            }

            string xml_str = "";
            mUdxSchema.FormatToXmlStream(ref xml_str);
            return xml_str;
        }

        /// <summary>
        /// 获取数据映射方法支持的读取节点个数
        /// </summary>
        /// <returns>返回支持读取节点的个数，Int类型</returns>
        public static int getCapabilityCount_imp()
        {
            //! TODO
            getSchema_imp();
            if (mCapabilities == null)
            {
                mCapabilities = new List<UdxNodeSchema>();
                mCapabilities.Add(mUdxSchema.getChildNode(0).getChildNode(0));
                mCapabilities.Add(mUdxSchema.getChildNode(0).getChildNode(1));
                mCapabilities.Add(mUdxSchema.getChildNode(0).getChildNode(2));
                mCapabilities.Add(mUdxSchema.getChildNode(0).getChildNode(3));
                mCapabilities.Add(mUdxSchema.getChildNode(0).getChildNode(4));
                mCapabilities.Add(mUdxSchema.getChildNode(0).getChildNode(5));
                mCapabilities.Add(mUdxSchema.getChildNode(0).getChildNode(6));
                mCapabilities.Add(mUdxSchema.getChildNode(0).getChildNode(7));
                mCapabilities.Add(mUdxSchema.getChildNode(0).getChildNode(8));

                mCapabilities.Add(mUdxSchema.getChildNode(1).getChildNode(0).getChildNode(0));
                mCapabilities.Add(mUdxSchema.getChildNode(1).getChildNode(0).getChildNode(1));
                mCapabilities.Add(mUdxSchema.getChildNode(1).getChildNode(0).getChildNode(2));
                mCapabilities.Add(mUdxSchema.getChildNode(1).getChildNode(0).getChildNode(3));
                mCapabilities.Add(mUdxSchema.getChildNode(1).getChildNode(0).getChildNode(4));

                mCapabilities.Add(mUdxSchema.getChildNode(1).getChildNode(0).getChildNode(5).getChildNode(0));

                mCapabilities.Add(mUdxSchema.getChildNode(2));
            }
            return mCapabilities.Count;
        }

        /// <summary>
        /// 获取数据映射方法支持读取的节点名称
        /// </summary>
        /// <param name="idx">读取节点的索引</param>
        /// <returns>返回支持读取节点的名称，String类型</returns>
        public static string getCapabilityName_imp(int idx)
        {
            //! TODO
            if (idx < 0 || idx >= mCapabilities.Count)
                return "";
            return mCapabilities[idx].getName();
        }

        /// <summary>
        /// 设置数据映射方法在读取某个节点时，List类型节点的Index信息
        /// </summary>
        /// <param name="node_idx">节点的顺序Index</param>
        /// <param name="read_idx">节点的读取Index</param>
        /// <returns>返回是否设置成功</returns>
        public static bool setNodeReadIndex_imp(int node_idx, int read_idx)
        {
            //! TODO
            mReadNodeIndex_Collection[node_idx] = read_idx;
            return false;
        }

        /// <summary>
        /// 从原始的文件格式中读取UDX Data
        /// </summary>
        /// <param name="file_name">原始文件全路径</param>
        /// <param name="node_name">读取的节点名称，为空的话就全部读取</param>
        /// <param name="save_name">保存的UDX文件全路径</param>
        /// <returns>返回是否读取成功</returns>
        public static bool readToNode_imp(string file_name, string node_name, string save_name)
        {
            //! TODO
            if (node_name == "")
            {
                //! TODO
                //! 进行整体的转换
                Console.Write("TODO");
            }
            else if (node_name == "UpperLeftX")
            {
                //! TODO
                UdxNodeSchema node_schema = mUdxSchema.getChildNode(0).getChildNode(0);
                UdxDataset dataset = new UdxDataset();
                UDXUtility.constructNode(node_schema, dataset);
                UdxNode node_data = dataset.getChildNode(0);

                ((UdxKernelRealValue)(node_data.getKernel())).setTypedValue(12.34);

                if (save_name == "")
                {
                    string xml_str = dataset.FormatToXmlStream();
                    Console.Write(xml_str);
                }
                else
                {
                    dataset.FormatToXmlFile(save_name);
                }
                return true;
            }
            //! .......

            return false;
        }

        /// <summary>
        /// 从UDX文件写入到原始的数据格式
        /// </summary>
        /// <param name="udx_name">UDX数据的路径</param>
        /// <param name="save_name">原始格式数据的保存路径</param>
        /// <returns>返回是否写入成功</returns>
        public static bool writeFromNode(string udx_name, string save_name)
        {
            //! TODO
            UdxDataset dataset = new UdxDataset();
            dataset.LoadFromXmlFile(udx_name);

            UdxKernel pKernel;
            UdxKernelRealValue realKernel;
            UdxKernelIntValue intKernel;
            UdxKernelStringValue stringKernel;

            //////////////////////////////////////////////////////////////////////////
            pKernel = dataset.getChildNode(0).getChildNode(0).getKernel();
            realKernel = (UdxKernelRealValue)pKernel;
            double upperLeftX = realKernel.getTypedValue();

            pKernel = dataset.getChildNode(0).getChildNode(1).getKernel();
            realKernel = (UdxKernelRealValue)pKernel;
            double pixelWidth = realKernel.getTypedValue();

            pKernel = dataset.getChildNode(0).getChildNode(2).getKernel();
            realKernel = (UdxKernelRealValue)pKernel;
            double transParam1 = realKernel.getTypedValue();

            pKernel = dataset.getChildNode(0).getChildNode(3).getKernel();
            realKernel = (UdxKernelRealValue)pKernel;
            double upperLeftY = realKernel.getTypedValue();

            pKernel = dataset.getChildNode(0).getChildNode(4).getKernel();
            realKernel = (UdxKernelRealValue)pKernel;
            double transParam2 = realKernel.getTypedValue();

            pKernel = dataset.getChildNode(0).getChildNode(5).getKernel();
            realKernel = (UdxKernelRealValue)pKernel;
            double pixelHeight = realKernel.getTypedValue();

            pKernel = dataset.getChildNode(0).getChildNode(6).getKernel();
            intKernel = (UdxKernelIntValue)pKernel;
            int width = intKernel.getTypedValue();

            pKernel = dataset.getChildNode(0).getChildNode(7).getKernel();
            intKernel = (UdxKernelIntValue)pKernel;
            int height = intKernel.getTypedValue();

            pKernel = dataset.getChildNode(0).getChildNode(8).getKernel();
            intKernel = (UdxKernelIntValue)pKernel;
            int count = intKernel.getTypedValue();

            return false;
        }

    }
}
